# -*-coding:utf-8-*-
from abc import ABCMeta, abstractmethod

class A(object, metaclass=ABCMeta):
    field_a = 1

    def __init__(self, x, y, z):
        super().__init__(z)
        print('init_A')
        self.x = x
        self.y = y

    def foo(self):
        print('调用foo(self)', 'a')

    def foo_a(self):
        print('调用foo_a(self)', self.__dict__)

    @classmethod
    def class_method(cls):
        print('调用class_method(cls)', cls.__dict__)

    @staticmethod
    def echo():
        print('调用A的静态方法')

    @abstractmethod
    def abs_method(self): pass


class B(object):
    field_a = 2

    def __init__(self, z):
        print('init_B')
        self.z = z

    def foo(self):
        print('调用foo(self)', 'b')

    def foo_b(self):
        print('调用foo_b(self)', self.__dict__)


# 多重继承的时候,所有的基类的方法都可以继承,但属性需要手工初始化
#              如果派生类中没有__init__方法.默认获得第一个基类的所有属性
#               如果派生类中有__init__方法,所有的基类的属性都没有.需要手工逐一初始化!!
class C(A, B):

    # 类变量可以继承和覆盖.未覆盖时,父类类变量改变时子类调用时也会改变(本质是子类调用的是父类的类变量)
    field_a = 3

    def __init__(self):
        """
        单继承时这样写: super().__init__(1, 2)
        !!!钻石型继承时不要采用这样的方式初始化!!!: A.__init__(self, 1, 2),B.__init__(self, 3)
        """
        super().__init__(1, 2, 3)
        print('init_C')

    def foo(self):
        super().foo()
        print('调用重写foo(self)', self.__dict__)

    # 类方法可以继承,也可以重写和使用super()
    @classmethod
    def class_method(cls):
        super().class_method()
        print('调用重写class_method(cls)', cls.__dict__)

    # 静态方法可以继承和覆盖，不能重写和使用super()
    @staticmethod
    def echo():
        print('调用C的静态方法')

    def abs_method(self):
        print('实现父类A的抽象方法')


"""
调用父类方法时,按照mro()中的继承顺序进行查找;
所以当多继承时父类都有相同方法foo时,调用的是继承顺序靠前的那个父类的foo方法,
但如果靠前的那个父类方法中调用了super().foo()时,会继续向后调用其兄弟类的foo方法。

init方法也是一样，所以多继承时不要写成A.__init__(self),B.__init__(self)的形式,
钻石继承时会导致最顶上的类的init方法执行多次。

class A: 
    def __init__(self):
        super().__init__()
        print('run A.init')
    def x(self):
        super().x()
        print('run A.x')

class B:
    def __init__(self):
        print('run B.init')
    def x(self):
        print('run B.x')

class C(A,B):
    def __init__(self):
        super().__init__()
        print('run C.init')
    def x(self):
        super().x()
        print('run C.x')

C().x()

结果:
run B.init
run A.init
run C.init
run B.x
run A.x
run C.x
"""

if __name__ == '__main__':
    print(C.mro())
    c = C()
    # 调用父类的实例方法
    c.foo_a()
    c.foo_b()
    # 调用重写的父类的实例方法
    c.foo()
    # 调用重写的父类的类方法
    C.class_method()
    # 调用覆盖父类的静态方法
    C.echo()
    c.abs_method()